#include "heibai_chessboard_opencv.h"
#include "heibai_color.h"

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <opencv/cv.h>
#include <opencv/highgui.h> 

CHBChessBoardOpencv::CHBChessBoardOpencv(char * name)
{
	m_sWinName = new char[strlen(name)+1];
	strcpy(m_sWinName, name);

	m_img = cvCreateImage(cvSize(HEIBAI_SUM_WIDTH, HEIBAI_SUM_HEIGTH),IPL_DEPTH_8U,3);
	DrawBoardLine();
	cvNamedWindow(m_sWinName, CV_WINDOW_AUTOSIZE);
	//cvMoveWindow(m_sWinName, HEIBAI_SUM_WIDTH, HEIBAI_SUM_HEIGTH);
	cvShowImage(m_sWinName, m_img );
	m_k = 1;
	m_signal.m_k = 0;
	cvSetMouseCallback(m_sWinName, mouseSig,this);
}

CHBChessBoardOpencv::~CHBChessBoardOpencv()
{
	cvReleaseImage(&m_img );
	delete [] m_sWinName;
}

void CHBChessBoardOpencv::DrawBoardLine()
{
	DrawBack();
	DrawLine();
	DrawProfileChess();
}

void CHBChessBoardOpencv::DrawBack()
{
	char mychannel[3];
	mychannel[0] = HEIBAI_BACK >> 16;
	mychannel[1] = (HEIBAI_BACK & 0xff)>>8;
	mychannel[2] = HEIBAI_BACK & 0xff;
	char * data = m_img->imageData;
	int step = m_img->widthStep;
	int width = 0;
	int heigth = 0;
	for(heigth = 0; heigth < HEIBAI_SUM_HEIGTH; heigth++){
		for(width = 0; width < HEIBAI_SUM_WIDTH; width++){
			data[heigth*step+width*3]=mychannel[0];
			data[heigth*step+width*3+1]=mychannel[1];
			data[heigth*step+width*3+2]=mychannel[2];
		}
	}
}

void CHBChessBoardOpencv::ShowBoard()
{
	cvShowImage(m_sWinName, m_img );
}

void CHBChessBoardOpencv::DrawLine()
{
	int i;
	int nStart = HEIBAI_BRIM_WIDE_LENGTH+HEIBAI_NODE_LENGTH/2 + 1;
	int size = HEIBAI_NODE_LENGTH;
	int nEnd = nStart + 7*size;
	int nR = HEIBAI_LINE >> 16;
	int nB = (HEIBAI_LINE & 0XFF00) >> 8;
	int nG = HEIBAI_LINE & 0xff;
	for(i = 0; i < 8; i++){
		int x = nStart + i * size;
		cvLine(m_img, cvPoint(x, nStart), cvPoint(x, nEnd), cvScalar(nR,nB,nG), 1);
	}
	for(i = 0; i < 8; i++){
		int x = nStart + i * size;
		cvLine(m_img, cvPoint(nStart,x), cvPoint(nEnd,x), cvScalar(nR,nB,nG), 1);
	}
}

void CHBChessBoardOpencv::PutChess(int x, int y, int user)
{
	int nR,nB,nG;
	int nColor;
	if(user == USER1){
		nColor = USER_BLACK_COLOR;
	}else
		nColor = USER_WHITE_COLOR;
	nR = nColor >> 16;
	nB = (nColor & 0xff00) >> 8;
	nG = nColor & 0xff;
	int size = HEIBAI_NODE_LENGTH;
	int nStart = HEIBAI_BRIM_WIDE_LENGTH+HEIBAI_NODE_LENGTH/2 + 1;
	int nx = nStart + (x - 1) * size;
	int ny = nStart + (y - 1) * size;
	cvCircle(m_img, cvPoint(nx,ny), HEIBAI_CHELL_SIZE/4, cvScalar(nR,nB,nG), HEIBAI_CHELL_SIZE/2);
}

void CHBChessBoardOpencv::GetSignal(int &x, int &y)
{
	int re;
	do{
		re = cvWaitKey(30);
		if(re == -1 && cvGetWindowHandle(m_sWinName) == 0)
			  exit(0);
	}while(m_k != m_signal.m_k);
	m_k++;
	x = m_signal.m_mouse_x;
	y = m_signal.m_mouse_y;
}

void CHBChessBoardOpencv::mouseSig(int event, int x, int y, int flags, void * param)
{
	switch(event){
		case CV_EVENT_LBUTTONDOWN:
			((CHBChessBoardOpencv*)param)->SetSignal(HEIBAI_SIGNAL_MOUSE, x, y, 0);
	}
}

void CHBChessBoardOpencv::SetSignal(int sig, int x, int y, int key)
{
	int nStart = HEIBAI_BRIM_WIDE_LENGTH;
	int nx = (x - nStart)/HEIBAI_NODE_LENGTH + 1;
	int nxo = (x - nStart)%HEIBAI_NODE_LENGTH;
	int ny = (y - nStart)/HEIBAI_NODE_LENGTH + 1;
	int nyo = (y - nStart)%HEIBAI_NODE_LENGTH;
	if(nx > 0 && nx < 9 && nxo > 3 && nxo < HEIBAI_NODE_LENGTH - 3
			&& ny > 0 && ny < 9 && nyo > 3 && nyo < HEIBAI_NODE_LENGTH -3){
		m_signal.m_signal = sig;
		m_signal.m_key = key;
		m_signal.m_mouse_x = nx;
		m_signal.m_mouse_y = ny;
		m_signal.m_k = m_k;
	}
}

void CHBChessBoardOpencv::DrawProfileChess()
{
	int nR,nB,nG;
	int nColor = USER_BLACK_COLOR;
	nR = nColor >> 16;
	nB = (nColor & 0xff00) >> 8;
	nG = nColor & 0xff;
	cvCircle(m_img, cvPoint(HEIBAI_PROFILE_CHESS_CENTER_X,HEIBAI_PROFILE_CHESS_CENTER_Y1), HEIBAI_CHELL_SIZE/4, cvScalar(nR,nB,nG), HEIBAI_CHELL_SIZE/2);

	nColor = USER_WHITE_COLOR;
	nR = nColor >> 16;
	nB = (nColor & 0xff00) >> 8;
	nG = nColor & 0xff;
	cvCircle(m_img, cvPoint(HEIBAI_PROFILE_CHESS_CENTER_X,HEIBAI_PROFILE_CHESS_CENTER_Y2), HEIBAI_CHELL_SIZE/4, cvScalar(nR,nB,nG), HEIBAI_CHELL_SIZE/2);
}

void CHBChessBoardOpencv::SetProfile(int type, int user1Chess, int user2Chess, int user)
{
	int nR,nB,nG;
	int nColor = HEIBAI_TEXT;
	nR = nColor >> 16;
	nB = (nColor & 0xff00) >> 8;
	nG = nColor & 0xff;

	DrawProfileBack();

	CvFont font;
	double hScale=1.0;
	double vScale=1.0;
	int    lineWidth=1;
	cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth); 
	char buf[64];
	sprintf(buf,"%d",user1Chess);
	cvPutText (m_img,buf,cvPoint(HEIBAI_PROFILE_TEXT_X,HEIBAI_PROFILE_TEXT_Y1), &font, cvScalar(nR,nB,nG));
	sprintf(buf,"%d",user2Chess);
	cvPutText (m_img,buf,cvPoint(HEIBAI_PROFILE_TEXT_X,HEIBAI_PROFILE_TEXT_Y2), &font, cvScalar(nR,nB,nG));

	if(type == HEIBAI_PRO_TYPE_END)
		sprintf(buf, "win");
	else if(type == HEIBAI_PRO_TYPE_PLAY)
		sprintf(buf, "play");
	cvPutText (m_img,buf,cvPoint(HEIBAI_PROFILE_TEXT_X + HEIBAI_CHELL_SIZE,HEIBAI_PROFILE_CHESS_CENTER_Y), &font, cvScalar(nR,nB,nG));

	if(user == USER1)
		nColor = USER_BLACK_COLOR;
	else
		nColor = USER_WHITE_COLOR;
	nR = nColor >> 16;
	nB = (nColor & 0xff00) >> 8;
	nG = nColor & 0xff;
	cvCircle(m_img, cvPoint(HEIBAI_PROFILE_TEXT_X - HEIBAI_CHELL_SIZE /2,HEIBAI_PROFILE_CHESS_CENTER_Y), HEIBAI_CHELL_SIZE/4, cvScalar(nR,nB,nG), HEIBAI_CHELL_SIZE/2);
}

void CHBChessBoardOpencv::DrawProfileBack()
{
	char mychannel[3];
	mychannel[0] = HEIBAI_BACK >> 16;
	mychannel[1] = (HEIBAI_BACK & 0xff)>>8;
	mychannel[2] = HEIBAI_BACK & 0xff;
	char * data = m_img->imageData;
	int step = m_img->widthStep;
	int width = 0;
	int heigth = 0;
	for(heigth = HEIBAI_BRIM_WIDE_LENGTH; heigth < HEIBAI_SUM_HEIGTH - HEIBAI_BRIM_WIDE_LENGTH; heigth++){
		for(width = HEIBAI_BRIM_WIDE_LENGTH * 2 + HEIBAI_BOARD_LENGTH ; width < HEIBAI_SUM_WIDTH - HEIBAI_BRIM_WIDE_LENGTH; width++){
			data[heigth*step+width*3]=mychannel[0];
			data[heigth*step+width*3+1]=mychannel[1];
			data[heigth*step+width*3+2]=mychannel[2];
		}
	}
	DrawProfileChess();
}
